package com.cn.fw4j.mvc.servlet.impl;

import groovy.lang.GroovyObject;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cn.fw4j.json.inter.IFw4jJson;
import com.cn.fw4j.mvc.annotation.Fw4jController;
import com.cn.fw4j.mvc.annotation.Fw4jDecorator;
import com.cn.fw4j.mvc.page.inter.IPageTemplate;
import com.cn.fw4j.util.ClassHelper;
import com.cn.fw4j.util.PropertiesHelper;
import com.cn.fw4j.util.groovy.GroovyLoaderHelper;
import com.cn.fw4j.util.request.parameter.InParam;
import com.cn.fw4j.util.request.parameter.OutParam;

public abstract class ServletController{
	
	private final static Logger logger = LoggerFactory.getLogger(ServletController.class);
	
	/**
	 * 打印json
	 * @param response
	 * @param c
	 * @param obj
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException
	 * @throws IOException
	 */
	protected void printJson(HttpServletResponse response, String c,
			Object obj) throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, IOException {
		if(c.startsWith("JSON:")){
			String json = c.replace("JSON:", "");
			logger.debug(json);
			IFw4jJson ifw4jJson = (IFw4jJson)Class.forName(json).newInstance();
			response.getWriter().print(ifw4jJson.toJson(obj));
		}
	}
	
 	/**
 	 * 调用模板
 	 * @param request
 	 * @param response
 	 * @param template
 	 * @param out
 	 * @param obj
 	 * @throws ClassNotFoundException
 	 * @throws InstantiationException
 	 * @throws IllegalAccessException
 	 */
 	protected void pageTemplate(HttpServletRequest request,
			HttpServletResponse response, String template,
			OutParam out, Object obj)
			throws ClassNotFoundException, InstantiationException,
			IllegalAccessException {
		if(obj != null && (obj.toString().startsWith("request:")||obj.toString().startsWith("redirect:"))){
			String path  = obj.toString();
			Class<?> pcl = ClassHelper.loadClass(template);
			IPageTemplate ipt = (IPageTemplate) pcl.newInstance();
			ipt.Template(path, out, request, response);
		}
	}
     
    /**
     * 组织参数
     * @param request
     * @param response
     * @param m
     * @return
     */
	protected List<Object> parameters(HttpServletRequest request,
			HttpServletResponse response, Method m,
			OutParam out) {
		Class<?>[] paramTypes = m.getParameterTypes();
		List<Object> params = new ArrayList<Object>(); 
		for(Class<?> type : paramTypes){
			if(type.equals(HttpServletRequest.class)){
				params.add(request);
			}else if(type.equals(HttpServletResponse.class)){
				params.add(response);
			}else if(type.equals(HttpSession.class)){
				params.add(request.getSession());
			}else if(type.equals(HashMap.class)){
				params.add(new HashMap<Object,Object>());
			}else if(type.equals(ArrayList.class)){
				params.add(new ArrayList<Object>());
			}else if(type.equals(LinkedHashMap.class)){
				params.add(new LinkedHashMap<Object,Object>());
			}else if(type.equals(Set.class)){
				params.add(new LinkedHashSet<Object>());
			}else if(type.equals(OutParam.class)){
				params.add(out);
			}else if(type.equals(InParam.class)){
				Map<String,String[]> maps= request.getParameterMap();
				InParam inmap = new InParam();
				for(String key : maps.keySet()){
					String[] vals = maps.get(key);
					if(vals.length == 1)
						inmap.put(key,vals[0]);
					else
						inmap.put(key, vals);
				}
				params.add(inmap);
			}
		}
		if(params.size()>0)
			return params;
		return null;
	}
	
	/**
	 * URL根 
	 * @param request
	 * @return
	 */
	protected  String basePath(HttpServletRequest request){
   	 	return request.getContextPath();
    }
	
	/**
	 * URL
	 * @param request
	 * @return
	 */
	protected  String urlPath(HttpServletRequest request){
	   	 String base = basePath(request);
	   	 String url = request.getRequestURI();
	   	 if(!base.equals("/")){
	   		 url = url.replace(base, "");
	   	 }
	   	 return url;
    }
	/**
	 * 输出参数
	 * @param request
	 * @return
	 */
   protected OutParam newOutParam(HttpServletRequest request){
    	 OutParam out = new OutParam();
		 out.put("base", basePath(request));
		 return out;
    }
   
   /**
    * 获取模板
    * @param cl
    * @return
    */
   protected String getTemplate(Class<?> cl){
		String temp = PropertiesHelper.get("fw4j.properties", "FW4J_PAGE_TEMPLATE");
		if(temp != null) return temp;
		return cl.getAnnotation(Fw4jController.class).template();
	}
   
   protected <T> Object wrapper(T obj,Method m,List<Object> args){
	   if(obj instanceof GroovyObject){
		   
	   }else if(obj instanceof Object){
		   
	   }
	   return null;
   }
   protected Object decorator(Method m,List<Object> args){
	    if(m != null){
			Fw4jDecorator dr = m.getAnnotation(Fw4jDecorator.class);
			if(dr != null){
				try {
					switch(dr.type().compareTo(dr.type())){
					case 0:
						Class<?> javaClass = ClassHelper.loadClass(dr.value());
						Method drm= ClassHelper.getMethodByName(javaClass.getMethods(), dr.method());
						return drm.invoke(javaClass.newInstance(), args.toArray());
					case 1:
						GroovyObject go = GroovyLoaderHelper.getInstance().getGroovyInstance(dr.value());
						return go.invokeMethod(dr.method(), args);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
	    }
	    return null;
   }
}
